home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / pp / pp-6.0 / Lib / qmgr / comms.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-18  |  13.6 KB  |  624 lines

  1. /* comm.c: ROS communication routines */
  2.  
  3. # ifndef lint
  4. static char Rcsid[] = "@(#)$Header: /xtel/pp/pp-beta/Lib/qmgr/RCS/comms.c,v 6.0 1991/12/18 20:23:58 jpo Rel $";
  5. # endif
  6.  
  7. /*
  8.  * $Header: /xtel/pp/pp-beta/Lib/qmgr/RCS/comms.c,v 6.0 1991/12/18 20:23:58 jpo Rel $
  9.  *
  10.  * $Log: comms.c,v $
  11.  * Revision 6.0  1991/12/18  20:23:58  jpo
  12.  * Release 6.0
  13.  *
  14.  */
  15.  
  16. #include "util.h"
  17. #include "qmgr-int.h"
  18. #include "Qmgr-types.h"
  19. #include "Qmgr-ops.h"
  20. #include "qmgr.h"
  21. #include <varargs.h>
  22. #include "consblk.h"
  23.  
  24. #define PP_SERVICE    "pp qmgr"
  25.  
  26. static void    advise(), ros_advise(), acs_advise();
  27.  
  28. static int    general_error();
  29.  
  30. typedef struct client_dispatch {
  31.     char            *ds_name;
  32.     int                ds_operation;
  33.     IFP                ds_argument;
  34.     modtyp            *ds_fr_mod;
  35.     int                ds_fr_index;
  36.     IFP                ds_result;
  37.     IFP                ds_error;
  38.     char            *ds_help;
  39. } Client_dispatch;
  40.  
  41. /* CLIENT STRUCTURE */
  42.  
  43. extern int    arg_channelread(), res_channelread();
  44. #define channelread_error    general_error
  45.  
  46. extern int    arg_channelcontrol(), res_channelcontrol();
  47. #define channelcontrol_error    general_error
  48.  
  49. extern int    arg_mtaread(), res_mtaread();
  50. #define mtaread_error        general_error
  51.  
  52. extern int    arg_mtacontrol(), res_mtacontrol();
  53. #define mtacontrol_error    general_error
  54.  
  55. extern int    arg_readchannelmtamessage(), res_readchannelmtamessage();
  56. #define readchannelmtamessage_error    general_error
  57.  
  58. extern int    arg_msgcontrol(), res_msgcontrol();
  59. #define msgcontrol_error        general_error
  60.  
  61. extern int    arg_quecontrol(), res_quecontrol();
  62. #define quecontrol_error    general_error
  63.  
  64. extern int    res_qmgrStatus();
  65. #define qmgrStatus_error    general_error
  66.  
  67. extern int    arg_filter ();
  68. #define filter_error        general_error
  69.  
  70. static int    arg_quit();
  71.  
  72. struct client_dispatch client_dispatches[] = {
  73. {
  74.     "channelread", operation_Qmgr_channelread,
  75.     arg_channelread, &_ZUNIV_mod, _ZUTCTimeUNIV,
  76.     res_channelread, channelread_error,
  77.     "read information on channels"
  78. },
  79. {
  80.     "channelcontrol", operation_Qmgr_channelcontrol,
  81.     arg_channelcontrol, &_ZQmgr_mod, _ZChannelControlQmgr,
  82.     res_channelcontrol, channelcontrol_error,
  83.     "control channel"
  84. },
  85. {
  86.     "mtaread", operation_Qmgr_mtaread,
  87.     arg_mtaread, &_ZQmgr_mod, _ZMtaReadQmgr,
  88.     res_mtaread, mtaread_error,
  89.     "read information on mtas"
  90. },
  91. {
  92.     "mtacontrol", operation_Qmgr_mtacontrol,
  93.     arg_mtacontrol, &_ZQmgr_mod, _ZMtaControlQmgr,
  94.     res_mtacontrol, mtacontrol_error,
  95.     "control mta"
  96. },
  97. {
  98.     "readchannelmtamessage", operation_Qmgr_readChannelMtaMessage,
  99.     arg_readchannelmtamessage, &_ZQmgr_mod, _ZMsgReadQmgr,
  100.     res_readchannelmtamessage, readchannelmtamessage_error,
  101.     "read a set of messages"
  102. },
  103. {
  104.     "msgcontrol", operation_Qmgr_msgcontrol,
  105.     arg_msgcontrol, &_ZQmgr_mod, _ZMsgControlQmgr,
  106.     res_msgcontrol, msgcontrol_error,
  107.     "control msg"
  108. },
  109. {
  110.     "quecontrol", operation_Qmgr_qmgrControl,
  111.     arg_quecontrol, &_ZQmgr_mod, _ZQMGRControlQmgr,
  112.     res_quecontrol, quecontrol_error,
  113.     "control qmgr"
  114. },
  115. {
  116.     "qmgrStatus", operation_Qmgr_qmgrStatus, NULLIFP,
  117.     &_ZQmgr_mod, _ZQmgrStatusQmgr,
  118.     res_qmgrStatus, qmgrStatus_error,
  119.     "control qmgr"
  120. },
  121. {
  122.     "readmsginfo", operation_Qmgr_readmsginfo, arg_filter,
  123.     &_ZQmgr_mod, _ZReadMessageArgumentQmgr,
  124.     res_readchannelmtamessage, filter_error,
  125.     "read messages"
  126. },
  127. {
  128.     "quit",     0,      arg_quit,
  129.     NULL, 0, NULLIFP, NULLIFP,
  130.     "terminate the association and exit"
  131. },
  132. {
  133.     NULL
  134. }
  135. };
  136.  
  137. static struct client_dispatch *get_dispatch(id)
  138. {
  139.     struct client_dispatch *ix;
  140.  
  141.     for (ix = client_dispatches;
  142.          NULL != ix && NULLCP != ix->ds_name;
  143.          ix++)
  144.         if (id == ix -> ds_operation)
  145.             return ix;
  146.     return (struct client_dispatch *) NULL;
  147. }
  148.  
  149.  
  150. /*   */
  151.  
  152. int    initiate_op (ad, op_id, args, pid, fnx, errbuf)
  153. int    ad;
  154. int    op_id;
  155. char    **args;
  156. int    *pid;
  157. IFP    fnx;
  158. char    errbuf[];
  159. {
  160.     int                        result, id;
  161.     caddr_t                 in = NULL;
  162.     struct RoSAPindication  rois;
  163.     struct client_dispatch    *ds;
  164.     register struct RoSAPindication    *roi = &rois;
  165.     register struct RoSAPpreject       *rop = &roi -> roi_preject;
  166.  
  167.     in = NULL;
  168.  
  169.     if ((ds = get_dispatch(op_id)) == NULL) {
  170.         advise(errbuf, "Unknown dispatch number [%d]",
  171.                op_id);
  172.         return NOTOK;
  173.     }
  174.  
  175.     if (ds -> ds_argument
  176.         && (*ds -> ds_argument) (ad, args, &in) == NOTOK)
  177.         return NOTOK;
  178.  
  179.     id = RyGenID (ad);
  180.     if (pid) *pid = id;
  181.     switch (result = RyStub (ad, 
  182.                  table_Qmgr_Operations, 
  183.                  ds -> ds_operation, 
  184.                  id,
  185.                  NULLIP, 
  186.                  in, 
  187.                  ds -> ds_result, 
  188.                  ds -> ds_error, 
  189.                  ROS_ASYNC, 
  190.                  roi)) {
  191.         case NOTOK:        /* failure */
  192.         if (ROS_FATAL(rop->rop_reason)) {
  193.             ros_advise (errbuf, rop, "STUB");
  194.             result = DONE;
  195.         }
  196.         break;
  197.         
  198.         case OK:        /* should get a result/error response */
  199.         (void) newcopblk (ad, id, fnx);
  200.         break;
  201.         
  202.         case DONE:        /* got RO-END? */
  203.         advise (errbuf, "%s", "got RO-END.INDICATION");
  204.         break;
  205.         default:
  206.         advise (errbuf, "unknown return from RyStub=%d", result);
  207.         /* NOTREACHED */
  208.         result = NOTOK;
  209.         break;
  210.     }
  211.  
  212.     if (ds -> ds_fr_mod && in)
  213.         (void) fre_obj (in,
  214.                 ds -> ds_fr_mod -> md_dtab[ds -> ds_fr_index],
  215.                 ds -> ds_fr_mod, 1);
  216.     return result;
  217. }
  218.  
  219. /*   */
  220.  
  221. int result_op (ad, pid, errbuf)
  222. int    ad;
  223. int    *pid;
  224. char    errbuf[];
  225. {
  226.     caddr_t    out;
  227.     struct RoSAPindication    rois;
  228.     register struct RoSAPindication *roi = &rois;
  229.     register struct RoSAPpreject   *rop = &roi -> roi_preject;
  230.  
  231.     errbuf[0] = '\0';
  232.  
  233.     switch (RyWait (ad, pid, &out, NOTOK, roi)) {
  234.         case NOTOK:
  235.         if (rop -> rop_reason == ROS_TIMER)
  236.             break;
  237.         PP_TRACE (("RyWait returned NOTOK"));
  238.         ros_advise (errbuf, rop, "STUB");
  239.         if (ROS_FATAL (rop -> rop_reason))
  240.             return DONE;
  241.         break;
  242.  
  243.         case OK:
  244.         PP_TRACE (("RyWait returned OK"));
  245.         break;
  246.  
  247.         case DONE:
  248.         return DONE;
  249.     }
  250.  
  251.     return OK;
  252. }
  253.     
  254. /*   */
  255.  
  256. static PE    fillin_passwd(user, passwd, auth, errbuf)
  257. char    *user;
  258. char    *passwd;
  259. int    auth;
  260. char    errbuf[];
  261. {
  262.     PE    ret;
  263.     struct type_Qmgr_BindArgument    *ba;
  264.  
  265.     ba = (struct type_Qmgr_BindArgument *)
  266.         smalloc(sizeof *ba);
  267.     switch ((ba->offset = auth)) {
  268.         case type_Qmgr_BindArgument_noAuthentication:
  269.         default:
  270.         break;
  271.         case type_Qmgr_BindArgument_weakAuthentication:
  272.         ba->un.weakAuthentication =
  273.             (struct type_Qmgr_WeakAuthentication *)
  274.                 smalloc(sizeof(struct type_Qmgr_WeakAuthentication));
  275.         ba->un.weakAuthentication->username = str2qb(user,
  276.                                  strlen(user),
  277.                                  1);
  278.         if (NULLCP != passwd  && '\0' != *passwd)
  279.             ba->un.weakAuthentication->passwd = str2qb(passwd,
  280.                                    strlen(passwd),
  281.                                    1);
  282.         else
  283.             ba->un.weakAuthentication->passwd = NULL;
  284.         break;
  285.  
  286.     }
  287.  
  288.     if (encode_Qmgr_BindArgument (&ret, 1, NULLCP, 0, ba) == NOTOK) {
  289.         advise(errbuf,
  290.                "failed to encode BindArgument [%s]", PY_pepy);
  291.         free_Qmgr_BindArgument(ba);
  292.         return NULLPE;
  293.     }
  294.     free_Qmgr_BindArgument(ba);
  295.     ret->pe_context = 3;
  296.     return ret;
  297. }
  298.  
  299. static BindResult    *convert_BindResult(acc, errbuf)
  300. struct AcSAPconnect    *acc;
  301. char    *errbuf;
  302. {
  303.     struct type_Qmgr_BindResult    *br;
  304.  
  305.     if (acc->acc_ninfo >= 1) {
  306.         if (decode_Qmgr_BindResult (acc->acc_info[0],
  307.                         1, NULLIP, NULLVP, &br) == NOTOK) {
  308.             advise (errbuf,
  309.                 "failed to parse BindResult [%s]",
  310.                 PY_pepy);
  311.             return (BindResult *) NOTOK;
  312.         } else {
  313.             BindResult    *ret = (BindResult *) 
  314.                 calloc(1, sizeof(*ret));
  315.             switch (br->result) {
  316.                 case int_Qmgr_result_acceptedFullAccess:
  317.                 ret->access = FULL_ACCESS;
  318.                 break;
  319.                 case int_Qmgr_result_acceptedLimitedAccess:
  320.                 default:
  321.                 ret->access = LIMITED_ACCESS;
  322.                 break;
  323.             }
  324.             
  325.             if (NULL != br->information)
  326.                 ret->info = qb2str(br->information);
  327.             if (NULL != br->version)
  328.                 ret->version = qb2str(br->version);
  329.  
  330.             free_Qmgr_BindResult(br);
  331.             return ret;
  332.         }
  333.     }
  334.     return NULL;
  335. }
  336.  
  337. void free_BindResult (br)
  338. BindResult    *br;
  339. {
  340.     if (br -> info)
  341.         free(br -> info);
  342.     if (br -> version)
  343.         free(br->version);
  344.     free((char *) br);
  345. }
  346.  
  347. int init_connect (host, user, passwd, auth, pid, errbuf, bindRes)
  348. char    *host, *user, *passwd;
  349. int    auth;
  350. int    *pid;
  351. char    errbuf[];
  352. BindResult    **bindRes;
  353. {
  354.     struct SSAPref             sfs;
  355.     register struct SSAPref     *sf;
  356.     register struct PSAPaddr     *pa;
  357.     AEI                    aei;
  358.     OID                    ctx,
  359.                     tmppci;
  360.     struct PSAPctxlist         pcs;
  361.     register struct PSAPctxlist     *pc = &pcs;
  362.     struct RoSAPindication         rois;
  363.     register struct RoSAPindication    *roi = &rois;
  364.     register struct RoSAPpreject     *rop = &roi -> roi_preject;
  365.     struct AcSAPconnect         accs;
  366.     register struct AcSAPconnect       *acc = &accs;
  367.     struct AcSAPindication      acis;
  368.     register struct AcSAPindication    *aci = &acis;
  369.     register struct AcSAPabort     *aca = &aci -> aci_abort;
  370.     int                result;
  371.     PE                passwdpep;
  372.  
  373.     if ((pa = str2paddr (host)) == NULLPA) {
  374.         if ((aei = _str2aei (host, PP_SERVICE, QMGR_CTX_OID, 
  375.                      0, dap_user, dap_passwd)) == NULLAEI) {
  376.             advise (errbuf, "%s: unknown entity",
  377.                 host);
  378.             return NOTOK;
  379.         }
  380.         if ((pa = aei2addr (aei)) == NULLPA) {
  381.             advise (errbuf, "%s", "address translation failed");
  382.             return NOTOK;
  383.         }
  384.     }
  385.     if ((ctx = oid_cpy (QMGR_AC)) == NULLOID) {
  386.         advise (errbuf, "%s", "out of memory");
  387.         return NOTOK;
  388.     }
  389.  
  390.     if ((tmppci = oid_cpy (QMGR_PCI)) == NULLOID) {
  391.         advise (errbuf, "%s", "out of memory"); 
  392.         return NOTOK;
  393.     }
  394.     pc -> pc_nctx = 1;
  395.     pc -> pc_ctx[0].pc_id = 1;
  396.     pc -> pc_ctx[0].pc_asn = tmppci;
  397.     pc -> pc_ctx[0].pc_atn = NULLOID;
  398.  
  399.     if ((sf = addr2ref (PLocalHostName ())) == NULL) {
  400.         sf = &sfs;
  401.         (void) bzero ((char *) sf, sizeof *sf);
  402.     }
  403.  
  404.     if ((passwdpep = fillin_passwd(user, passwd, auth, errbuf))
  405.         == NULLPE)
  406.         return NOTOK;
  407.  
  408.     result = AcAsynAssocRequest (ctx, NULLAEI, NULLAEI, NULLPA,
  409.                          pa, pc, NULLOID, 0,
  410.                          ROS_MYREQUIRE,
  411.                          SERIAL_NONE, 0, sf, 
  412.                          &passwdpep, 1,
  413.                          NULLQOS, acc, aci, 1);
  414.     pe_free(passwdpep);
  415.  
  416.     switch(result) {
  417.         case NOTOK:
  418.         acs_advise (errbuf, aca, "A-ASSOCIATE.REQUEST");
  419.         return NOTOK;
  420.         case CONNECTING_1:
  421.         case CONNECTING_2:
  422.         *pid = acc->acc_sd;
  423.         ACCFREE(acc);
  424.         PP_TRACE (("Association initiated"));
  425.         return result;
  426.         case DONE:
  427.         if (acc -> acc_result != ACS_ACCEPT) {
  428.             advise(errbuf,
  429.                    "Association rejected: [%s]",
  430.                    AcErrString (acc -> acc_result));
  431.             ACCFREE(acc)
  432.             return NOTOK;
  433.         }
  434.         PP_TRACE (("Association established"));
  435.         if (RoSetService (acc->acc_sd, RoPService, roi) == NOTOK) {
  436.             ros_advise (errbuf, rop, "set RO/PS fails");
  437.             ACCFREE(acc);
  438.             return NOTOK;
  439.         }
  440.         PP_TRACE (("Service set"));
  441.         *pid = acc->acc_sd;
  442.         *bindRes = convert_BindResult(acc, errbuf);
  443.         ACCFREE(acc);
  444.         return DONE;
  445.         default:
  446.         advise(errbuf,
  447.                "Bad response from AcAsynAssocRequest [%d]",
  448.                result);
  449.         return NOTOK;
  450.     }
  451. }
  452.  
  453. /*   */
  454.  
  455. int retry_connect (id, errbuf, bindRes)
  456. int    id;
  457. char    errbuf[];
  458. BindResult    **bindRes;
  459. {
  460.     struct AcSAPconnect         accs;
  461.     register struct AcSAPconnect       *acc = &accs;
  462.     struct AcSAPindication  acis;
  463.     register struct AcSAPindication *aci = &acis;
  464.     register struct AcSAPabort *aca = &aci -> aci_abort;
  465.     struct RoSAPindication rois;
  466.     register struct RoSAPindication *roi = &rois;
  467.     register struct RoSAPpreject *rop = &roi -> roi_preject;
  468.     int    result;
  469.  
  470.     PP_TRACE (("acsap_retry(%d)", id));
  471.     switch (result = AcAsynRetryRequest (id, acc, aci)) {
  472.         case CONNECTING_1:
  473.         case CONNECTING_2:
  474.         ACCFREE(acc);
  475.         return result;
  476.         case NOTOK:
  477.         acs_advise (errbuf, aca, "A-ASSOCIATE.REQUEST");
  478.         ACCFREE(acc);
  479.         return NOTOK;
  480.         case DONE:
  481.         if (acc -> acc_result != ACS_ACCEPT) {
  482.             advise(errbuf,
  483.                    "Association Rejected: [%s]",
  484.                    AcErrString (acc -> acc_result));
  485.             ACCFREE(acc);
  486.             return NOTOK;
  487.         }
  488.         if (RoSetService (acc->acc_sd, RoPService, roi) == NOTOK) {
  489.             ros_advise (errbuf, rop, "set RO/PS fails");
  490.             ACCFREE(acc);
  491.             return NOTOK;
  492.         }
  493.         *bindRes = convert_BindResult(acc, errbuf);
  494.         ACCFREE(acc);
  495.         return DONE;
  496.         default:
  497.         advise (errbuf, "%s", "Bad response from AcAsynRetryRequest");
  498.         return NOTOK;
  499.     }
  500. }
  501.  
  502. /*   */
  503.  
  504. char    errBuf[BUFSIZ];
  505.  
  506. /* ARGSUSED */
  507. static int  arg_quit (ad, args, arg)
  508. int    ad;
  509. char    **args, **arg;
  510. {
  511.     return release_connect(ad, errBuf);
  512. }
  513.  
  514. int  release_connect (sd, errbuf)
  515. int     sd;
  516. char    errbuf[];
  517. {
  518.     struct AcSAPrelease acrs;
  519.     register struct AcSAPrelease   *acr = &acrs;
  520.     struct AcSAPindication  acis;
  521.     register struct AcSAPindication *aci = &acis;
  522.     register struct AcSAPabort *aca = &aci -> aci_abort;
  523.  
  524.     if (AcRelRequest (sd, ACF_NORMAL, NULLPEP, 0, NOTOK, acr, aci) == NOTOK) {
  525.         acs_advise (errbuf, aca, "A-RELEASE.REQUEST");
  526.         return DONE;
  527.     }
  528.  
  529.     if (!acr -> acr_affirmative) {
  530.         (void) AcUAbortRequest (sd, NULLPEP, 0, aci);
  531.         advise (errbuf,    "Release rejected by peer: %d",
  532.             acr -> acr_reason);
  533.     }
  534.  
  535.     ACRFREE (acr);
  536.     PP_TRACE (("Association released"));
  537.  
  538.     return DONE;
  539. }
  540.  
  541. /* ARGSUSED */
  542. static int    general_error(ad, id, err, parameter, roi)
  543. int    ad, id, err;
  544. caddr_t    parameter;
  545. struct RoSAPindication    *roi;
  546. {
  547.     struct RyError    *rye;
  548.  
  549.     if (RY_REJECT == err) {
  550.         advise(errBuf, "%s", RoErrString ((int) parameter));
  551.         return OK;
  552.     }
  553.  
  554.     if (NULL != (rye = finderrbyerr (table_Qmgr_Errors, err)))
  555.         advise(errBuf, "Error: %s", rye -> rye_name);
  556.     else
  557.         advise(errBuf, "Error: %d", err);
  558.  
  559.     return OK;
  560. }
  561.  
  562. /*   */
  563.  
  564. static void ros_advise(buf, rop, event)
  565. char    *buf;
  566. struct RoSAPpreject    *rop;
  567. char    *event;
  568. {
  569.     char    buffer[BUFSIZ];
  570.     if (rop->rop_cc > 0)
  571.         (void) sprintf (buffer,
  572.                  "[%s] %*.*s",
  573.                  RoErrString (rop->rop_reason),
  574.                  rop->rop_cc, rop->rop_cc,
  575.                  rop->rop_data);
  576.     else
  577.         (void) sprintf (buffer,
  578.                 "[%s]",
  579.                 RoErrString(rop->rop_reason));
  580.     advise(buf, "%s: %s", event, buffer);
  581. }
  582.  
  583. static void    acs_advise (buf, aca, event)
  584. char    *buf;
  585. register struct AcSAPabort *aca;
  586. char   *event;
  587. {
  588.     char    buffer[BUFSIZ];
  589.  
  590.     if (aca -> aca_cc > 0)
  591.         (void) sprintf (buffer, "[%s] %*.*s",
  592.                 AcErrString (aca -> aca_reason),
  593.                 aca -> aca_cc, aca -> aca_cc, aca -> aca_data);
  594.     else
  595.         (void) sprintf (buffer, "[%s]",
  596.                 AcErrString (aca -> aca_reason));
  597.  
  598.     advise (buf, "%s: %s (source %d)", event, buffer,
  599.         aca -> aca_source);
  600. }
  601.  
  602. #ifndef lint
  603. static void advise (va_alist)
  604. va_dcl
  605. {
  606.     char    *buf;
  607.     va_list    ap;
  608.  
  609.     va_start (ap);
  610.  
  611.     buf = va_arg(ap, char *);
  612.     _asprintf(buf, NULLCP, ap);
  613.     va_end(ap);
  614. }
  615. #else
  616. /* VARARGS2 */
  617.  
  618. static void advise(what, fmt)
  619. char    *what, *fmt;
  620. {
  621.     advise(what, fmt);
  622. }
  623. #endif
  624.